package com.itxuhang.servlet;

import com.itxuhang.adapter.HandlerAdapter;
import com.itxuhang.adapter.HttpRequestHandlerApater;
import com.itxuhang.adapter.SimpleControllerHandlerApater;
import com.itxuhang.mapping.BeanNameUrlHandlerMapping;
import com.itxuhang.mapping.HandlerMapping;
import com.itxuhang.mapping.SimpleUrlHandlerMapping;
import com.itxuhang.model.ModelAndView;
import com.itxuhang.springframework.factory.BeanFactory;
import com.itxuhang.springframework.factory.DefaultListableBeanFactory;
import com.itxuhang.springframework.reader.XmlBeanDefinitionReader;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 定义出来的统一接收请求参数和返回响应结果的Servlet类
 */
public class DispatchServlet extends AbstractServlet{

    private List<HandlerMapping> handlerMappings = new ArrayList<>();
    private List<HandlerAdapter> handlerAdapters = new ArrayList<>();

    private DefaultListableBeanFactory beanFactory;

    private static final String contextConfigLocation = "contextConfigLocation";
    @Override
    public void init(ServletConfig config) throws ServletException {
        String location = config.getInitParameter(contextConfigLocation);
        beanFactory = new DefaultListableBeanFactory();
        // 解析Document对象，加载BeanDefinition集合
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        reader.loadBeanDefinitions(location);

        // 初始化所有的被Spring单例管理的Bean
        beanFactory.getBeansByType(Object.class);

        // 初始化策略集合
        initStrategies();

//        handlerMappings.add(new BeanNameUrlHandlerMapping());
//        handlerMappings.add(new SimpleUrlHandlerMapping());
//        handlerAdapters.add(new HttpRequestHandlerApater());
//        handlerAdapters.add(new SimpleControllerHandlerApater());

    }

    private void initStrategies() {
        initHandlerMappings();
        initHandlerAdapters();
    }

    private void initHandlerAdapters() {
        handlerAdapters = beanFactory.getBeansByType(HandlerAdapter.class);
    }

    private void initHandlerMappings() {
        handlerMappings = beanFactory.getBeansByType(HandlerMapping.class);
    }

    @Override
    protected void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 根据请求，找到合适的处理类来处理请求
        Object handler = getHandler(req);
        // 处理类怎么写（参数怎么写，返回值怎么写）
        // 处理类的理类的参数应该有req和resp，但是每个人可能对于类和方法的声明都不一样
        // 也就是说，没有统一的编写处理类的标准（接口），那么最终在调用处理类的方法时，就会特别麻烦
        if (handler == null) {
            return;
        }

        // 调用处理类去处理请求
        HandlerAdapter ha = getHandlerAdapter(handler);
        if (ha == null){
            return ;
        }
        ModelAndView mv = ha.handleRequest(handler,req,resp);

        /*if(handler instanceof HttpRequestHandler){
            ((HttpRequestHandler)handler).handleRequest(req,resp);
        }else if(handler instanceof SimpleControllerHandler){
            ((SimpleControllerHandler)handler).handleRequest(req,resp);
        }*/
        // 返回处理结果
    }

    private HandlerAdapter getHandlerAdapter(Object handler) {
        for (HandlerAdapter ha : handlerAdapters) {
            if (ha.supports(handler)){
                return ha;
            }
        }
        return null;
    }

    private Object getHandler(HttpServletRequest req) {
        //HandlerMapping接口
        for (HandlerMapping hm : handlerMappings){
            Object handler = hm.getHandler(req);
            if(handler != null){
                return handler;
            }
        }

        return null;
    }
}
